#include "MaterialUnlitNodeModel.h"

#include "MaterialGraph/Pin/MaterialGraphPinModel.h"
#include "Object/NewObject.h"

void RMaterialUnlitNodeModel::FirstTimeInitializeObject()
{
    auto ColorPin = NewObject<RMaterialGraphPinModel>(this);
    ColorPin->bIsOutput = false;
    ColorPin->ValueType = EMaterialGraphValueType::Vector3D;
    Inputs.Add(ColorPin);

    auto OpacityPin = NewObject<RMaterialGraphPinModel>(this);
    OpacityPin->bIsOutput = false;
    OpacityPin->ValueType = EMaterialGraphValueType::Vector1D;
    Inputs.Add(OpacityPin);
}

CString RMaterialUnlitNodeModel::GenerateExpression()
{
    return U"outColor = vec4("+Inputs[0]->GetValueExpression()+U", "+Inputs[1]->GetValueExpression()+U");\n";
}

CString RMaterialUnlitNodeModel::GetShaderTemplate() const
{
    return 
U"\
#version 460\n\
#extension GL_ARB_separate_shader_objects : enable\n\
#extension GL_ARB_shading_language_420pack : enable\n\
\
layout (set=2, binding = 0) uniform SceneBufferObject \n\
{ \n\
    mat4 ProjectionView; \n\
    float CameraNear; \n\
    float CameraFar; \n\
\
    mat4 ProjectMatrix; \n\
    mat4 ViewMatrix; \n\
    vec3 CameraPosition; \n\
    vec3 CameraForwardDirection; \n\
    vec3 CameraRightDirection; \n\
    vec3 CameraUpDirection; \n\
} SceneBuffer; \n\
\
layout (location = 0) in vec3 inNormal;\n\
layout (location = 1) in vec2 inUV;\n\
layout (location = 2) in vec3 inWorldPos;\n\
layout (location = 3) in float inCameraNearPlane; \n\
layout (location = 4) in float inCameraFarPlane; \n\
\
layout (location = 0) out vec4 outColor; \n\
\
/*HEADERS_AREA*/                 \n\
float linearDepth(float depth)\n\
{\n\
	float z = depth * 2.0f - 1.0f; \n\
    return (2.0f * inCameraNearPlane * inCameraFarPlane)/(inCameraFarPlane + inCameraNearPlane - z * (inCameraFarPlane - inCameraNearPlane));  \n\
}\n\
\n\
vec3 GetNormalFromMap(vec3 InNormalTextureValue)\n\
{\n\
    vec3 tangentNormal=InNormalTextureValue*2.0-1.0;\n\
    vec3 Q1  = dFdx(inWorldPos);\n\
    vec3 Q2  = dFdy(inWorldPos);\n\
    vec2 st1 = dFdx(inUV);\n\
    vec2 st2 = dFdy(inUV);\n\
\n\
    vec3 N   = normalize(inNormal);\n\
    vec3 T  = normalize(Q1*st2.t - Q2*st1.t);\n\
    vec3 B  = -normalize(cross(N, T));\n\
    mat3 TBN = mat3(T, B, N);\n\
\n\
    return normalize(TBN * InNormalTextureValue);\n\
}\n\
\n\
void main()\n\
{\n\
    float Ao=1.f;\n\
	float Depth = linearDepth(gl_FragCoord.z);\n\
/*CALCULATE_AREA*/\n\
}\
"
;
}
